import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import moment from 'moment'
import cfg from '@/config/config'
import { type UserInfo } from '@/config/types'

import api from '@/api/auth'
import type { LoginForm, PasswordForm, RegisterForm } from '@/config/form'

export const useAuthStore = defineStore('auth', () => {
  const loading = ref<boolean>(false)
  const userInfo = ref<UserInfo | null>(null)
  const captcha = ref<string>('')

  const user = localStorage.getItem(cfg.USER) || null
  if (user != null) {
    userInfo.value = JSON.parse(user)
  }

  const isLoggedIn = computed(
    () =>
      userInfo.value !== null &&
      userInfo.value.token !== '' &&
      userInfo.value.expireTime > moment().valueOf()
  )

  const userToken = computed(() => {
    if (userInfo.value !== null && userInfo.value.token !== '') {
      return userInfo.value.token
    }
    return ''
  })

  async function login(form: LoginForm) {
    loading.value = true
    try {
      const res = await api.login(form)
      userInfo.value = res.data
      localStorage.setItem(cfg.USER, JSON.stringify(res.data))
      localStorage.setItem(cfg.TOKEN, res.data.token)
      localStorage.setItem(cfg.EXPIRE, res.data.expireTime)
    } finally {
      loading.value = false
    }
  }

  async function refreshCaptcha() {
    try {
      const res = await api.captcha()
      captcha.value = res.data
    } catch (e) {
      captcha.value = ''
    }
  }

  function logout() {
    userInfo.value = null
    localStorage.removeItem(cfg.USER)
    localStorage.removeItem(cfg.TOKEN)
    localStorage.removeItem(cfg.EXPIRE)
  }

  async function updatePassword(form: PasswordForm) {
    loading.value = true
    let result: boolean
    try {
      await api.password(form)
      result = true
    } catch (e) {
      result = false
    } finally {
      loading.value = false
    }
    return result
  }

  async function register(form: RegisterForm) {
    loading.value = true
    let result: boolean
    try {
      const res = await api.register(form)
      result = res.data
    } catch (e) {
      result = false
    } finally {
      loading.value = false
    }
    return result
  }

  return {
    loading,
    isLoggedIn,
    userInfo,
    userToken,
    captcha,

    login,
    logout,
    refreshCaptcha,
    updatePassword,
    register
  }
})
